﻿using Kaskelot.SP.UI.Analys.Data;
using Kaskelot.SP.UI.Analys.Domain;
using Kaskelot.SP.UI.Analys.ViewModel;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using Telerik.Windows.Controls;

namespace Kaskelot.SP.UI.Analys.Controls
{
	public partial class CheckboxQueryBuilder : UserControl
	{
		public event EventHandler<GenericEventArgs<Query>> FilterReady = delegate { };
		public event EventHandler<GenericEventArgs<List<Field>>> FieldsUpdated = delegate { };
		internal static string GlobalQueriesText = "Delade urval:";
		internal static string PersonalQueriesHeading = "Dina urval:";

		private CheckboxQueryBuilderViewModel viewModel
		{
			get
			{
				return this.DataContext as CheckboxQueryBuilderViewModel;
			}
		}
		public CheckboxQueryBuilder()
		{
			InitializeComponent();
		}

		public object DataContext
		{
			get { return base.DataContext; }
			set
			{
				base.DataContext = value;
				this.viewModel.PropertyChanged += viewModel_PropertyChanged;
			}
		}

		void viewModel_PropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)
		{
			if (e.PropertyName == "Query")
			{
				FieldsUpdated(this, new GenericEventArgs<List<Field>>(this.viewModel.Query.DisplayFields));
				this.FilterContainer.SetDataSource(this.viewModel.SelectedEntities);
				//this.FilterContainer.SetFilters(this.viewModel.Query.Filters);
			}
		}

		private void ShowQuerySelection_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
		{
			if (SavedQueryChoice.Visibility == System.Windows.Visibility.Collapsed)
			{
				this.SavedQueryChoice.Visibility = System.Windows.Visibility.Visible;
				this.SaveButton.Visibility = System.Windows.Visibility.Visible;
                this.DeleteButton.Visibility = System.Windows.Visibility.Visible;
				this.SelectSavedSelection.Style = Application.Current.Resources["QueryBuilderHeading"] as Style;
				this.CreateNewSelection.Style = Application.Current.Resources["QueryBuilderHeadingDisabled"] as Style;
			}
			else
			{
				this.SavedQueryChoice.Visibility = System.Windows.Visibility.Collapsed;
				this.SaveButton.Visibility = System.Windows.Visibility.Collapsed;
                this.DeleteButton.Visibility = System.Windows.Visibility.Collapsed;
				this.SelectSavedSelection.Style = Application.Current.Resources["QueryBuilderHeadingDisabled"] as Style;
				this.CreateNewSelection.Style = Application.Current.Resources["QueryBuilderHeading"] as Style;
                LoadQueries();
			}
		}

		private void SaveButton_Click(object sender, RoutedEventArgs e)
		{
			object content;
			Query currentQuery = this.viewModel.Query;
			
			if (currentQuery.IsPersonal == false && UserInfo.Instance.HasAdminPriveleges == false)
			{
				RadWindow.Alert("Du behöver administratörsbehörighet för att spara en global fråga. Använd spara som för att spara din personliga kopia av frågan.");
				return;
			}

			bool considerAsNew = currentQuery.Name == GlobalQueriesText;

			SavePrompt prompt = new SavePrompt();
			prompt.AdminPart.Visibility = UserInfo.Instance.HasAdminPriveleges ? Visibility.Visible : Visibility.Collapsed;
			prompt.cbIsGlobal.IsChecked = currentQuery.IsPersonal == false;
			prompt.QueryID = currentQuery.ID;
			content = prompt;

			DialogParameters param = new DialogParameters
			{
				Content = content,
				DefaultPromptResultValue = considerAsNew || (UserInfo.Instance.HasAdminPriveleges == false && currentQuery.IsPersonal == false) ? string.Empty : currentQuery.Name,
				Header = "Kaskelot",
				Closed = new EventHandler<WindowClosedEventArgs>(OnSavePromptClosed)
			};
			RadWindow.Prompt(param);			
		}

		private void ResetButton_Click(object sender, RoutedEventArgs e)
		{
			this.viewModel.Reset();
			GetEntities(delegate
			{
				LoadQueries();
			});
			ErrorHandler.Instance.ClearError();
			FilterReady(this, new GenericEventArgs<Query>(null));
			FieldsUpdated(this, new GenericEventArgs<List<Field>>(new List<Field>()));

			this.viewModel.SelectionModeSelectQuery = true;
			this.SelectSavedSelection.Style = Application.Current.Resources["QueryBuilderHeadingDisabled"] as Style;
			this.CreateNewSelection.Style = Application.Current.Resources["QueryBuilderHeading"] as Style;
			this.SavedQueryChoice.Visibility = System.Windows.Visibility.Collapsed;
		}

		private void DeleteButton_Click(object sender, RoutedEventArgs e)
		{
            if (this.SavedQueryChoice.SelectedItem != null)
            {
                Query item = (Query)this.SavedQueryChoice.SelectedItem;
                AnalyseServiceWrapper.Instance.DeleteQuery(item.ID,
                    (string result) =>
                    {
                        LoadQueries();
                        RadWindow.Alert(result);
                    },
                    (Exception ex) =>
                    {
                        ErrorHandler.Instance.HandleError(ex);
                    });
            }
		}

		private void SaveAsButton_Click(object sender, RoutedEventArgs e)
		{
			object content;

			if (UserInfo.Instance.HasAdminPriveleges)
			{
				SavePrompt prompt = new SavePrompt();
				content = prompt;
			}
			else
				content = "Spara personlig fråga";

			DialogParameters param = new DialogParameters
			{
				Content = content,
				Header = "Kaskelot",
				Closed = new EventHandler<WindowClosedEventArgs>(OnSavePromptClosed)
			};
			RadWindow.Prompt(param);
		}

		private void GoButton_Click(object sender, RoutedEventArgs e)
		{
			Query query = this.viewModel.Query;
			query.Filters = FilterContainer.GetCurrentFilters();
			FieldsUpdated(this, new GenericEventArgs<List<Field>>(query.DisplayFields));
			FilterReady(this, new GenericEventArgs<Query>(query));

			ErrorHandler.Instance.ClearError();
		}

		private void OnSavePromptClosed(object sender, WindowClosedEventArgs e)
		{
			bool isGlobal = false;
			int id = 0;
			var innerContentControl = ((RadConfirm)(RadConfirm)((RadWindow)sender).Content).Content;

			var saveprompt = innerContentControl as SavePrompt;
			isGlobal = saveprompt != null && saveprompt.cbIsGlobal.IsChecked.HasValue && saveprompt.cbIsGlobal.IsChecked.Value == true;
			id = saveprompt != null ? saveprompt.QueryID : 0;

			if (e.DialogResult == true)
			{
				if (!string.IsNullOrEmpty(e.PromptResult))
				{
					Query query = this.viewModel.Query;
					query.Filters = FilterContainer.GetCurrentFilters();
					//query.DisplayFields = TreeContainer.GetCurrentFields();
					//query.Entities = TreeContainer.GetCurrentEntities();
					query.Name = e.PromptResult;
					query.ID = id;

					ErrorHandler.Instance.ClearError();

					if (isGlobal == false)
					{
						AnalyseServiceWrapper.Instance.SavePersonalQuery(query,
							(string result) =>
							{
								LoadQueries();
								RadWindow.Alert(result);
							},
							(Exception ex) =>
							{
								ErrorHandler.Instance.HandleError(ex);
							});
					}
					else
					{
						AnalyseServiceWrapper.Instance.SaveGlobalQuery(query,
							(string result) =>
							{
								LoadQueries();
								RadWindow.Alert(result);
							},
							(Exception ex) =>
							{
								ErrorHandler.Instance.HandleError(ex);
							});
					}
				}
			}
		}

		private void GetEntities(Action onSuccess)
		{
			AnalyseServiceWrapper.Instance.GetEntities(
				//Success
				delegate(ObservableCollection<ViewModel.Entity> entities)
				{
					//this.DataContext = new ViewModel.CheckboxQueryBuilderViewModel();
					ViewModel.CheckboxQueryBuilderViewModel viewModel = new CheckboxQueryBuilderViewModel();
					viewModel.Query.Entities = entities.ToList();
					this.DataContext = viewModel;
					onSuccess();
				},
				//Error
				delegate(Exception ex)
				{
					ErrorHandler.Instance.HandleError(ex);
				});
		}

		private void LoadQueries()
		{
			this.viewModel.SavedQueries.Clear();

			AnalyseServiceWrapper.Instance.GetPersonalQueries(
				(List<Query> result) =>
				{
					this.viewModel.SavedQueries.Add(new Query { ID = 0, Name = GlobalQueriesText, Entities = this.viewModel.Query.Entities, Filters = new List<IFilterPart>() });
					result.Where(q => q.IsPersonal == false).ToList().ForEach(delegate(Query q)
					{
						this.viewModel.SavedQueries.Add(q);
					});
					this.viewModel.SavedQueries.Add(new Query { ID = 0, Name = PersonalQueriesHeading, Entities = this.viewModel.Query.Entities, Filters = new List<IFilterPart>() });
					result.Where(q => q.IsPersonal == true).ToList().ForEach(delegate(Query q)
					{
						this.viewModel.SavedQueries.Add(q);
					});

					// Tvinga fram en update i RadComboBox
					SavedQueryChoice.ItemsSource = null;
					SavedQueryChoice.ItemsSource = this.viewModel.SavedQueries;
				},
				(Exception ex) =>
				{
					ErrorHandler.Instance.HandleError(ex);
				});
		}

		private void SavedQueryChoice_SelectionChanged(object sender, Telerik.Windows.Controls.SelectionChangedEventArgs e)
		{
			if (this.SavedQueryChoice.SelectedItem != null)
			{
                this.viewModel.Reset();
				if (this.SavedQueryChoice.SelectedItem is Query && (((Query)this.SavedQueryChoice.SelectedItem).Name == GlobalQueriesText || ((Query)this.SavedQueryChoice.SelectedItem).Name == PersonalQueriesHeading))
				{					
					return;
				}

				try
				{
					Query item = (Query)this.SavedQueryChoice.SelectedItem;
                    this.viewModel.Query.Name = item.Name;
                    this.viewModel.Query.ID = item.ID;
                    this.viewModel.Query.IsPersonal = item.IsPersonal;

                    Entity primaryEntity = item.Entities.SingleOrDefault(p => p.IsPrimary == true);
                    foreach (Entity qEntity in item.Entities)
                    {
                        Entity entity = this.viewModel.Query.Entities.SingleOrDefault(p => p.Name == qEntity.Name);
                        entity.IsPrimary = qEntity.IsPrimary;
                        entity.Checked = qEntity.Checked;
                        foreach (Field qField in qEntity.Fields)
                        {
                            Field field = entity.Fields.Single(f => f.InternalName == qField.InternalName);
                            field.Checked = qField.Checked;
                        }
                    }
                    this.viewModel.PrimaryEntity = this.viewModel.Query.Entities.SingleOrDefault(p => p.Name == primaryEntity.Name);
					this.FilterContainer.SetFilters(item.Filters);
				}
				catch (Exception)
				{
				}
			}
		}
	}
}
